package lambdasinaction.chap5.my;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import lambdasinaction.chap4.MyDish;

/**
 * 规约操作，将流归约成一个值。 用函数式编程语言的术语来说，这成为折叠（fold） 因为你可以将整个操作看成把一张长长的纸（你的流）反复折叠成一个小方块，而这就是操作折叠的结果。
 *
 * @author Fish
 * @since 0.0.1 2018/7/25 19:00
 */
public class MyReducing {

  public static void main(String[] args) {
    /**
     * reduce接受两个参数
     * 一个初始值，这里是0
     * 一个 BinaryOperator<T> 来将两个元素结合起来产生一个新值，这里我们用的是lambda(a, b) -> a + b
     * Lambda反复结合每个元素，直到流被归纳成一个值
     */
    List<Integer> numbers = Arrays.asList(3, 4, 5, 1, 2);
    int sum = numbers.stream().reduce(0, (a, b) -> a + b);
    System.out.println(sum);

    /**
     * 你可以使用方法引用让这段代码更简洁
     * 在 Java8中，Integer类现在有了一个静态的 sum 方法来对两个数求和，这恰是我们想要的
     * 用不着反复用 Lambda写同一段代码了
     */
    int sum2 = numbers.stream().reduce(0, Integer::sum);

    // 计算最大值
    int max = numbers.stream().reduce(0, Integer::max);

    // 计算最小值
    Optional<Integer> min = numbers.stream().reduce(Integer::min);

    // 计算所有卡路里之和
    int calories = MyDish.menu.stream().map(MyDish::getCalories).reduce(0, Integer::sum);

  }

}
